package com.vecspace.dayu.code.service;

import java.io.File;
import java.util.*;

import com.vecspace.dayu.code.consts.ColumnType;
import com.vecspace.utils.*;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.base.CaseFormat;
import com.vecspace.dayu.code.dao.DataTableDao;
import com.vecspace.dayu.code.pojo.DataColumn;
import com.vecspace.dayu.code.pojo.DataTable;
import com.vecspace.dayu.code.pojo.Func;
import com.vecspace.dayu.code.pojo.Project;
import com.vecspace.exception.HException;

/**功能描述 DAYU-表视图定义,按顺序号进行left join的增、删、改查等业务操作的service类
 * @author wanghua
 */
@Service("dayu_dataTableService")
public class DataTableService {
	/** 根据ID查询 DAYU-表视图定义,按顺序号进行left join 
	 * @param id   主键值
	 * @return DataTable
	 * @throws Exception
	 * @author wanghua
	 */
	public DataTable getDataTable(Long id) throws Exception{
		return dataTableDao.getDataTable(id);
	}
	
	/**获取表信息及字段信息
	 * 
	 * @param datatableId
	 * @return
	 * @throws Exception 
	 * @author wanghua
	 */
	public DataTable getDataTableWithColumns(Long datatableId) throws Exception{
		DataTable dataTable = dataTableDao.getDataTable(datatableId);
		if(dataTable != null) {
			List<DataColumn> dbColumns = dataColumnService.getDataColumns(datatableId);
			dataTable.setColumns(dbColumns);
			if(dataTable.getForeignTableId() != null) {
				DataTable foreignTable = dataTableDao.getDataTable(dataTable.getForeignTableId());
				if(foreignTable != null) {
					dataTable.setForeignTable(foreignTable);
//					dataTable.setForeignTableName(foreignTable.getTableName());
				}
			}
		}
		return dataTable;
	}
	
	/**获取项目中所有注册的数据表
	 * 
	 * @param projectId
	 * @return
	 * @throws Exception
	 */
	public List<DataTable> getProjectDataTables(Long projectId) throws Exception{
		return dataTableDao.getProjectDataTables(projectId);
	}
	
	/**获取数据集涉及的数据表
	 * 
	 * @param funcId
	 * @return
	 * @throws Exception 
	 * @author wanghua
	 */
	public List<DataTable> getDataTables(Long funcId) throws Exception {
		return dataTableDao.getDataTables(funcId);
	}

	/**从pdm文件中读取表字段
	 * 
	 * @param projectId
	 * @param tableName
	 * @return
	 * @throws Exception 
	 * @author wanghua
	 * @reviewer  
	 * @createTime 2021年9月11日 下午10:41:33
	 */
	public List<DataColumn> getDataColumns(Long projectId, String tableName) throws Exception{
		Project project = projectService.getProject(projectId);
		Assert.throwz(project != null, "projectId不存在：" + projectId);
		
		String pdmRelatePath = project.getPdmFilePath();		
		DataTable table = this.readTableColumnsInfoFromPdm(pdmRelatePath, tableName);
		return table.getColumns();
	}

	/**根据tableName从pdm文件获取字段信息，并创建表记录和字段记录
	 *
	 * @param projectId
	 * @param funcId
	 * @param tableName
	 * @return
	 * @throws Exception
	 */
	public DataTable addDataTable(Long projectId, Long funcId, String tableName) throws Exception {
		DataTable table = this.readTableColumnsInfoFromPdm(projectId, tableName);
		table.setFuncId(funcId);
		this.saveDataTable(table, true, "");
		return table;
	}
	
	/**重新从pdm文件中同步表的字段
	 * 
	 * @param dataTableId
	 * @param loginId
	 * @throws Exception 
	 * @author wanghua
	 */
	public void syncColumns(Long dataTableId, String loginId) throws Exception {
		Assert.throwz(dataTableId != null && dataTableId != 0, "dataTableId不能为空");
		
		DataTable dataTable = this.getDataTable(dataTableId);
		Assert.throwz(dataTable != null, "dataTableId不存在：" + dataTableId);
		String tableName = dataTable.getTableName();
		if(StringUtils.isBlank(tableName))throw new HException("没有定义表名，无法从pdm文件中同步字段");

		Func func = funcService.getFunc(dataTable.getFuncId());
		Assert.throwz(func != null, "funcId不存在：" + dataTable.getFuncId());

		Project project = projectService.getProject(func.getProjectId());
		Assert.throwz(project != null, "projectId不存在：" + func.getProjectId());
		
		String pdmRelatePath = project.getPdmFilePath();		
		DataTable readTable = this.readTableColumnsInfoFromPdm(pdmRelatePath, tableName);
		
		this.syncColumns(dataTableId, readTable.getColumns(), loginId);		
	}
	
	public void syncColumns(Long dataTableId, List<DataColumn> validColumns, String loginId) throws Exception {
		Assert.throwz(dataTableId != null && dataTableId != 0, "dataTableId不能为空");
		if(validColumns == null || validColumns.size() == 0)return;
		List<DataColumn> dbColumns = dataColumnService.getDataColumns(dataTableId);
		
		List<DataColumn> deleteColumns = new ArrayList<>();
		List<DataColumn> addColumns = new ArrayList<>();
		List<DataColumn> modifiedColumns = new ArrayList<>();
		
		//已经删除的字段
		for(DataColumn dbColumn : dbColumns) {
			boolean exists = false;
			for(DataColumn validColumn : validColumns) {
				if(StringUtils.equalsIgnoreCase(validColumn.getColumnName(), dbColumn.getColumnName())) {
					exists = true;
					break;
				}
			}
			if(!exists) {
				deleteColumns.add(dbColumn);
			}
		}
		//新增的字段
		for(DataColumn validColumn : validColumns) {		
			boolean exists = false;
			for(DataColumn dbColumn : dbColumns) {
				if(StringUtils.equalsIgnoreCase(validColumn.getColumnName(), dbColumn.getColumnName())) {
					exists = true;
					break;
				}
			}
			if(!exists) {
				addColumns.add(validColumn);
			}
		}
		
		//改动的字段
		for(DataColumn dbColumn : dbColumns) {
			for(DataColumn validColumn : validColumns) {
				if(StringUtils.equalsIgnoreCase(validColumn.getColumnName(), dbColumn.getColumnName())) {
					if(this.modifyColumnProp(dbColumn, validColumn)) {
						modifiedColumns.add(dbColumn);
					}
					break;
				}
			}
		}
		
		
		for(DataColumn deleteColumn: deleteColumns) {
			dataColumnService.deleteDataColumn(deleteColumn.getId());
		}
		for(DataColumn addColumn: addColumns) {
			addColumn.setDatatableId(dataTableId);
			dataColumnService.saveDataColumn(addColumn, loginId);
		}
		for(DataColumn modifiedColumn: modifiedColumns) {
			dataColumnService.saveDataColumn(modifiedColumn, loginId);
		}
	}
	
	private boolean modifyColumnProp(DataColumn dbColumn, DataColumn othColumn) {
		boolean modified = false;
		if(!StringUtils.equals(dbColumn.getColumnCaption(), othColumn.getColumnCaption())) {
			dbColumn.setColumnCaption(othColumn.getColumnCaption());
			modified = true;
		}
		if(!StringUtils.equals(dbColumn.getDataType(), othColumn.getDataType())) {
			dbColumn.setDataType(othColumn.getDataType());
			modified = true;
		}
		
		if(!StringUtils.equals(dbColumn.getColumnType(), othColumn.getColumnType())) {
			dbColumn.setColumnType(othColumn.getColumnType());
			modified = true;
		}

		if(!StringUtils.equals(dbColumn.getCodeType(), othColumn.getCodeType())) {
			dbColumn.setCodeType(othColumn.getCodeType());
			modified = true;
		}
		if(!StringUtils.equals(dbColumn.getUnit(), othColumn.getUnit())) {
			dbColumn.setUnit(othColumn.getUnit());
			modified = true;
		}
		if(!StringUtils.equals(dbColumn.getRefTableName(), othColumn.getRefTableName())) {
			dbColumn.setRefTableName(othColumn.getRefTableName());
			modified = true;
		}
		if(!StringUtils.equals(dbColumn.getRefIdColumn(), othColumn.getRefIdColumn())) {
			dbColumn.setRefIdColumn(othColumn.getRefIdColumn());
			modified = true;
		}
		if(!StringUtils.equals(dbColumn.getRefNameColumn(), othColumn.getRefNameColumn())) {
			dbColumn.setRefNameColumn(othColumn.getRefNameColumn());
			modified = true;
		}
		if(!StringUtils.equals(dbColumn.getRefNameColumnAliasName(), othColumn.getRefNameColumnAliasName())) {
			dbColumn.setRefNameColumnAliasName(othColumn.getRefNameColumnAliasName());
			modified = true;
		}		

		if(dbColumn.getDataLength() == null || !dbColumn.getDataLength().equals(othColumn.getDataLength())) {
			dbColumn.setDataLength(othColumn.getDataLength());
			modified = true;
		}
		if(dbColumn.getDataScale() == null || !dbColumn.getDataScale().equals(othColumn.getDataScale())) {
			dbColumn.setDataScale(othColumn.getDataScale());
			modified = true;
		}
		if(dbColumn.getOrdnum() == null || !dbColumn.getOrdnum().equals(othColumn.getOrdnum())) {
			dbColumn.setOrdnum(othColumn.getOrdnum());
			modified = true;
		}
		return modified;
	}
	
	/**获取所有表名称
	 * 
	 * @param projectId
	 * @return 
	 * @throws DocumentException 
	 * @author wanghua
	 */
	public List<DataTable> getTableNames(Long projectId) throws Exception{
		Project project = this.projectService.getProject(projectId);
		if(project == null)return Collections.emptyList();
		String pdmFilePath = project.getPdmFilePath();
		return readTableNames(pdmFilePath);
	}
	
	/**获取所有表名称
	 * 
	 * @param pdmRelatePath pdm文件在服务器上的相对路径 project.pdmFilePath
	 * @return 
	 * @throws DocumentException 
	 * @author wanghua
	 */
	public List<DataTable> readTableNames(String pdmRelatePath) throws DocumentException{
		List<DataTable> tables = new ArrayList<>();
		Assert.throwz(pdmRelatePath != null && pdmRelatePath.length() > 0, "项目没有上传pdm文件");
		String pdmPath = projectService.getAbsPdmFilePath(pdmRelatePath);
		File pdmFile = new File(pdmPath);
		if(!pdmFile.exists()) throw new HException("pdm文件不存在：" + pdmPath);

		SAXReader saxReader = new SAXReader();
		Document xmldoc = saxReader.read(pdmFile);
		@SuppressWarnings("unchecked")
		List<Node> tableNodes = xmldoc.selectNodes("//o:Table");
		for(Node tableNode: tableNodes) {
			String tableName = XmlUtils.readChildInnerText(tableNode, "a:Code");
			if(tableName != null && tableName.length() > 0) {
				tableName = tableName.trim().toUpperCase();
			}else {
				continue;
			}

			DataTable dataTable = new DataTable();
			String tableCaption = XmlUtils.readChildInnerText(tableNode, "a:Name");
			if(tableCaption == null || tableCaption.trim().length() == 0) {
				tableCaption = tableName;
			}
			dataTable.setTableName(tableName);
			dataTable.setTableCaption(tableCaption);

			String tableNameMain = tableName;//.substring(prixIdx+1);
			int prixIdx = tableName.indexOf("_");
			if(prixIdx < 4) {
				 tableNameMain = tableName.substring(prixIdx+1);
			}

			String className = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableNameMain);
			dataTable.setClassName(className);

			tables.add(dataTable);
		}
		return tables;
	}

	/**
	 * 从pdm文件中获取表和字段信息
	 * @param projectId
	 * @param tableName
	 * @return
	 * @throws Exception
	 */
	public DataTable readTableColumnsInfoFromPdm(Long projectId, String tableName) throws Exception {
		Project project = this.projectService.getProject(projectId);
		if(project == null)return null;
		String pdmFilePath = project.getPdmFilePath();
		return  readTableColumnsInfoFromPdm(pdmFilePath, tableName);
	}
	/**从pdm文件中获取字段信息
	 * 
	 * @param pdmRelatePath pdm文件在服务器上的相对路径 project.pdmFilePath
	 * @param tableName
	 * @return 如果pdm中不存在tableName命名的表，则返回null。
	 * @throws Exception 
	 * @author wanghua
	 */
	public DataTable readTableColumnsInfoFromPdm(String pdmRelatePath, String tableName) throws Exception {
		Assert.throwz(pdmRelatePath != null && pdmRelatePath.length() > 0, "项目没有上传pdm文件");
		String pdmPath = projectService.getAbsPdmFilePath(pdmRelatePath);
		File pdmFile = new File(pdmPath);
		if(!pdmFile.exists()) throw new HException("pdm文件不存在：" + pdmPath);

		SAXReader saxReader = new SAXReader();
		Document xmldoc = saxReader.read(pdmFile);		
		@SuppressWarnings("unchecked")
		List<Node> tableNodes = xmldoc.selectNodes("//o:Table");
		Node domainNodes = xmldoc.selectSingleNode("//c:Domains");

		Node tableNode = null;
		for(Node tableNode2: tableNodes) {
			String tableName2 = XmlUtils.readChildInnerText(tableNode2, "a:Code");
			if(tableName2 != null) tableName2 = tableName2.trim().toUpperCase();
			if(StringUtils.equalsIgnoreCase(tableName, tableName2)) {
				tableNode = tableNode2;
				break;
			}
		}
		List<DataColumn> dataColumns = new ArrayList<>();
		if(tableNode != null) {
			DataTable dataTable = new DataTable();
			String tableCaption = XmlUtils.readChildInnerText(tableNode, "a:Name");
			String tableComments = XmlUtils.readChildInnerText(tableNode, "a:Comment");
			if(tableComments == null) tableComments = "";

			if(tableComments.contains("link-files=true")){
				dataTable.setAttachmentType("3");
			}else if(tableComments.contains("link-images=true")){
				dataTable.setAttachmentType("2");
			}else if(tableComments.contains("link-image=true")){
				dataTable.setAttachmentType("1");
			}
			if(tableComments.contains("row-lock=true")){
				dataTable.setUseMasterLock(true);
			}
			if(tableComments.contains("master-lock=true")){
				dataTable.setUseMasterLock(true);
			}

			String tableNamePrix = "";
			int tableNamePrixIdx1 = tableComments.indexOf("prix=");
			if(tableNamePrixIdx1 >= 0){
				tableNamePrixIdx1 += 5;
				int tableNamePrixIdx2 = StringHelper.firstIndexOfChar(tableComments, " ,;，；|", tableNamePrixIdx1);
				if(tableNamePrixIdx2 < 0) tableNamePrixIdx2 = tableComments.length();
				if(tableNamePrixIdx2 > tableNamePrixIdx1) {
					tableNamePrix = tableComments.substring(tableNamePrixIdx1, tableNamePrixIdx2);
					tableNamePrix = tableNamePrix.toUpperCase();
				}
			}
			if(tableCaption == null || tableCaption.trim().length() == 0) {
				tableCaption = tableName;
			}
			dataTable.setTableName(tableName);
			dataTable.setTableCaption(tableCaption);

			String tableNameMain = tableName.toUpperCase();
			if(tableNamePrix.length()>0 && tableNameMain.startsWith(tableNamePrix)){
				tableNameMain = tableNameMain.substring(tableNamePrix.length());
			}
			if(tableNameMain.startsWith("T_")) tableNameMain = tableNameMain.substring(2);

			String className = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableNameMain);
			dataTable.setClassName(className);

			boolean foundNameColumn = false; //是否已经识别到名称字段
			Node columnsNode = tableNode.selectSingleNode("c:Columns");
			if(columnsNode != null) {
				@SuppressWarnings("unchecked")
				List<Node> columnNodes = columnsNode.selectNodes("o:Column");
				int columnOrdnum = 0;
				for(Node columnNode : columnNodes) {
					columnOrdnum += 10;
					String columnName = XmlUtils.readChildInnerText(columnNode, "a:Code");
					String columnLabel = XmlUtils.readChildInnerText(columnNode, "a:Name");
					String dataType = XmlUtils.readChildInnerText(columnNode, "a:DataType");
					String dataLenStr = XmlUtils.readChildInnerText(columnNode, "a:Length");
					String precisionStr = XmlUtils.readChildInnerText(columnNode, "a:Precision");
//					String commnets = XmlUtils.readChildInnerText(columnNode, "a:Comment");
					String options = XmlUtils.readChildInnerText(columnNode, "a:PhysicalOptions");
					String identityFlag = XmlUtils.readChildInnerText(columnNode, "a:Identity");
					if("ID".equalsIgnoreCase(columnName) || "ID_".equals(columnName) || "OID".equals(columnName)){
						options = "";//ID字段的options是作为参考存在的，不要对其解析
					}
					String custDataType = "";
					String domainCode = "";
					if(domainNodes != null) {
						Node domainNode = columnNode.selectSingleNode("c:Domain");
						if (domainCode != null) {
							String domainId = XmlUtils.readChildAttrValue(domainNode, "o:PhysicalDomain", "Ref");
							if (StringUtils.isNotBlank(domainId)) {
								Node physicalDomainNode = domainNodes.selectSingleNode(String.format("o:PhysicalDomain[@Id='%s']", domainId));
								if(physicalDomainNode != null){
									domainCode = XmlUtils.readChildInnerText(physicalDomainNode, "a:Code");
								}
							}
						}
					}

					//如果使用domain为 boolean 或者 bool，则设置custDataType为boolean，在后续生成代码时会将其考虑为Boolean类型
					if("boolean".equalsIgnoreCase(domainCode) || "bool".equalsIgnoreCase(domainCode)){
						custDataType = "boolean";
						dataType = "boolean";
					}else if("date".equalsIgnoreCase(domainCode)){
						dataType = "date";
					}else if("datetime".equalsIgnoreCase(domainCode)){
						dataType = "datetime";
					}else if("time".equalsIgnoreCase(domainCode)){
						dataType = "datetime";
					}else if("yuan".equalsIgnoreCase(domainCode)){
						dataType = "yuan";
					}

					if(columnLabel == null || columnLabel.length() == 0) columnLabel = columnName;					
					columnName = columnName.toUpperCase();

					String codeType = "";
					String unit = XmlUtils.readChildInnerText(columnNode, "a:Unit");
					boolean required = false;
					boolean searchField = false;
					String searchValueType = "";
					boolean groupBy = false;
					String aggFunc = "";
					String validationRules = "";
					boolean cellMenu = false;
					String charsetType = "";
					String refTableName = "";
					String refIdColumn = ""; //ID 外键字段名
					String refNameColumn = ""; //ID 外键字段名
					String refNameColumnAlias = "";//PROJECT_ID //  外键字段名别名
					if(options != null && options.length() > 0) {
						String[] optionsArr = options.split(";|；");
						for(String option : optionsArr) {
							if(option == null || option.length() == 0)continue;
							int eqIdx = option.indexOf("=");
							if(eqIdx > 0 && eqIdx+1<options.length()) {
								String kname = option.substring(0, eqIdx).trim();
								String kvalue = option.substring(eqIdx+1).trim();
								if("codetype".equalsIgnoreCase(kname)) {
									codeType = kvalue;
									if(codeType != null) codeType = codeType.trim().toUpperCase();
								}else if("input".equalsIgnoreCase(kname)) {
									custDataType = kvalue;
									if(custDataType != null) custDataType = custDataType.trim().toLowerCase();
								}
								else if("unit".equalsIgnoreCase(kname)) {
									unit = kvalue;
									if(unit != null) unit = unit.trim();
								}
								else if("required".equalsIgnoreCase(kname)) {
									if("true".equalsIgnoreCase(kvalue)) required = true;
								}
								else if("search".equalsIgnoreCase(kname)) {
									if("true".equalsIgnoreCase(kvalue)) searchField = true;
								}else if("search-value-type".equalsIgnoreCase(kname)) {
									searchValueType = kvalue;
								}else if("groupby".equalsIgnoreCase(kname)) {
									if("true".equalsIgnoreCase(kvalue)) groupBy = true;
								}else if("agg-func".equalsIgnoreCase(kname)) {
									aggFunc = kvalue;
								}else if("validation-rules".equalsIgnoreCase(kname)) {
									validationRules = kvalue;
								}else if("cell-menu".equalsIgnoreCase(kname)) {
									if("true".equalsIgnoreCase(kvalue)) cellMenu = true;
								}else if("lang".equalsIgnoreCase(kname)) {
									charsetType = kvalue;
								}else if("ref".equalsIgnoreCase(kname)) {// ref=TBM_PROJECT.ID,NAME PROJECT_NAME
									String refInfo = kvalue;
									if(refInfo != null) {
										refInfo = refInfo.trim().toUpperCase();
										int dotIdx = refInfo.indexOf(".");
										if(dotIdx > 0) {
											refTableName = refInfo.substring(0, dotIdx); //TBM_PROJECT
											String refColumnsStr = refInfo.substring(dotIdx + 1);//ID,NAME PROJECT_NAME
											if(refColumnsStr == null) refColumnsStr = "";
											String[] refColumnArr = refColumnsStr.split(",|，");
											if(refColumnArr.length > 0) {
												refIdColumn = refColumnArr[0].trim();
											}
											if(refColumnArr.length > 1) {
												String refNameColumnStr = refColumnArr[1];
												if(refNameColumnStr == null) refNameColumnStr = "";
												refNameColumnStr = refNameColumnStr.trim();
												int blankIdx = refNameColumnStr.indexOf(" ");
												if(blankIdx > 0) {
													refNameColumn = refNameColumnStr.substring(0, blankIdx).trim();
													refNameColumnAlias = refNameColumnStr.substring(blankIdx).trim();
												}
											}
										}
									}
								}
							}
						}
					}
					if(dataType != null && dataType.indexOf("(")>0){
						dataType = dataType.substring(0, dataType.indexOf("(")).trim();
					}
					int dataLen = Convert.toInt(dataLenStr, 0);
					int precision = Convert.toInt(precisionStr, 0);
					DataColumn column = new DataColumn();
					column.setColumnName(columnName);
					column.setColumnCaption(columnLabel);
					column.setDataType(dataType);
					column.setDataLength(dataLen);
					column.setDataScale(precision);
					column.setCustDataType(custDataType);
					column.setCodeType(codeType);
					column.setUnit(unit);
					column.setRequired(required);
					column.setIsSearchField(searchField);
					column.setSearchValueType(searchValueType);
					column.setIsGroupby(groupBy);
					column.setAggregateFunc(aggFunc);
					column.setValidationRules(validationRules);
					column.setCellMenu(cellMenu);
					column.setCharsetType(charsetType);
					column.setRefTableName(refTableName);
					column.setRefIdColumn(refIdColumn);
					column.setRefNameColumn(refNameColumn);
					column.setRefNameColumnAliasName(refNameColumnAlias);
					column.setOrdnum(columnOrdnum);
					
					//column_type: 1主键字段，2外键字段，3名称字段，4父ID字段，5租户字段，0普通字段
					if("1".equals(identityFlag) || "ID".equals(columnName) || "ID_".equals(columnName) || "OID".equals(columnName)) {
						column.setColumnType(ColumnType.KEY_COLUMN);
						dataTable.setIdColumnName(columnName);
					}else if(StringUtils.isNotBlank(refTableName)) {//columnName.endsWith("_ID") ||
						column.setColumnType(ColumnType.REF_COLUMN);
						if(StringUtils.isBlank(dataTable.getParentIdColumnName())) {
							dataTable.setParentIdColumnName(columnName);
						}
					}else if("NAME".equals(columnName) || "NAME_".equals(columnName) || columnName.endsWith("_NAME")) {
						if(!foundNameColumn) {
							column.setColumnType(ColumnType.NAME_COLUMN);
							foundNameColumn = true;
							dataTable.setNameColumnName(columnName);
						}
					}else if("PARENT_ID".equals(columnName) || "PID".equals(columnName)) {
						column.setColumnType(ColumnType.PARENT_ID_COLUMN);
						dataTable.setRecursion(true);
						dataTable.setParentIdColumnName(columnName);
					}else if("TENANT_ID".equals(columnName) || "TENANT_ID_".equals(columnName)) {
						column.setColumnType(ColumnType.TENANT_COLUMN);
					}else if("ORDNUM".equals(columnName) || "ORDIANL".equals(columnName) || "ORDER_".equals(columnName) || "ORDER_NUM".equals(columnName)) {
						column.setColumnType(ColumnType.ORDER_COLUMN);
						dataTable.setOrderColumnName(columnName);
					}else {
						column.setColumnType("");
					}
					
					dataColumns.add(column);
				}
			}
			dataTable.setColumns(dataColumns);

			return dataTable;
		}else {
			return null;
		}
	}

	/***将页面上传入的对象转为持久化对象（如果页面对象是一个新对象，则insert;否则从数据库库查询出已有的对象item2，将传入的值赋值给item2，然后将item2 update到数据库）
	 * 根据页面上放置的属性个数，需要对下面的属性设置进行调整。
	 * 对于无法在页面上进行修改的属性，不要进行设值。
	 * @param item item是由页面传递过来的对象，item中的属性并不完整，对于在页面上没有展示的属性，item中一律会是空值，而数据库中这些属性可以是有值的
	 * @return DataTable
	 * @throws Exception
	 * @author wanghua
	 */
	public DataTable saveViewDataTable(DataTable item, String loginUserId) throws Exception {
		if (item == null){
			return null;
		}
		/*** 下面开始对item对象的页面传值进行校验，如必填项，格式等 ***/
		//Assert.throwz(StringUtils.isNotBlank() , "条件不满足时抛出异常");
		/*** 结束校验 ***/
		
		DataTable item2;
		if (NumberUtil.isNotNullZero(item.getId())) {
			/**从数据库中取出原始对象，将从页面传过来的新值赋值给原始对象，并将原始对象再保存到数据库中 **/
			item2 = getDataTable(item.getId());
			if (item2 != null) {
				/*** 将页面上的新值逐一赋值，不在页面上的属性不要进行赋值 ***/
				//item2.setDatasetId(item.getDatasetId());//更新数据集ID
				item2.setTableName(item.getTableName());//更新功能ID
				item2.setTableAliasName(item.getTableAliasName());//更新表别名(统一小写)
				item2.setTableCaption(item.getTableCaption());//更新表中文名
				item2.setClassName(item.getClassName());//更新类名
				item2.setTableRelationSubtype(item.getTableRelationSubtype());
				item2.setRecursion(item.getRecursion());
				//item2.setViewSql(item.getViewSql());
				item2.setIdColumnName(item.getIdColumnName());//更新类名
				item2.setNameColumnName(item.getNameColumnName());//更新类名
				item2.setParentIdColumnName(item.getParentIdColumnName());//更新类名
				item2.setOrderColumnName(item.getOrderColumnName());//更新类名
				item2.setFilterColumnName(item.getFilterColumnName());//
				item2.setForeignColumnName(item.getForeignColumnName());//外键字段
				item2.setForeignTableId(item.getForeignTableId());//外键表id
				item2.setAttachmentTableName(item.getAttachmentTableName());
				item2.setAttachmentBusinessIdColumn(item.getAttachmentBusinessIdColumn());
				item2.setAttachmentIdColumn(item.getAttachmentIdColumn());
				item2.setAttachmentNameColumn(item.getAttachmentNameColumn());
				item2.setAttachmentOrderColumn(item.getAttachmentOrderColumn());
				item2.setUseRowLock(item.getUseRowLock());
				item2.setUseMasterLock(item.getUseMasterLock());
				item2.setAttachmentType(item.getAttachmentType());
				item2.setOrdnum(item.getOrdnum());//更新顺序号

				/**end**/
			} else {
				item2 = item;
			}
		}else{ //item是新增加的对象
			item2 = item;
		}
		saveDataTable(item2, true, loginUserId);
		return item2;
	}
	
	/** 插入或修改 DAYU-表视图定义,按顺序号进行left join ，item中的所有属性都会更新到数据库中（包括属性值为null的，也会将null更新到数据库，覆盖之前的值）。
	 * @param item	要保存的对象
	 * @return void
	 * @throws Exception
	 * @author wanghua
	 */
	public void saveDataTable(DataTable item, boolean loadColumnsFromPdm, String loginId) throws Exception{
		if (item == null){
			return;
		}
		/*** 下面开始对item对象进行校验，如逻辑关系等 ***/
		Assert.throwz(NumberUtil.isNotNullZero(item.getFuncId()), "DataTable.FuncId不能为空");
		/*** 结束校验 ***/
		Date date = new Date();
		boolean adding = false;
		if (NumberUtil.isNullOrZero(item.getId())) {
			adding = true;
			item.setId(null);
			item.setCreateTime(date);
			item.setCreateUser(loginId);//更新记录创建人ID

		} else {

		}
		dataTableDao.saveDataTable(item);
		if(adding && loadColumnsFromPdm){
			Long funcId = item.getFuncId();
			Func func = funcService.getFunc(funcId);
			List<DataColumn> dataColumns = this.getDataColumns(func.getProjectId(), item.getTableName());
			this.dataColumnService.saveColumns(item.getId(), dataColumns);
			item.setColumns(dataColumns);
		}
	}

	/**更新单个字段的值
	 * 
	 * @param id
	 * @param propName
	 * @param value
	 * @return
	 * @throws Exception 
	 * @author wanghua
	 */
	public void updateProp(Long id, String propName, Object value) throws Exception {
		String columnName;
		if("tableCaption".equals(propName)) {
			columnName = "TABLE_CAPTION";
		}else if("tableAliasName".equals(propName)) {
			columnName = "TABLE_ALIAS_NAME";
		}else if("tableNamePrix".equals(propName)) {
			columnName = "TABLE_NAME_PRIX";
		}else if("className".equals(propName)) {
			columnName = "CLASS_NAME";
		}else if("idColumnName".equals(propName)) {
			columnName = "ID_COLUMN_NAME";
		}else if("nameColumnName".equals(propName)) {
			columnName = "NAME_COLUMN_NAME";
		}else if("parentIdColumnName".equals(propName)) {
			columnName = "PARENT_ID_COLUMN_NAME";
		}else if("orderColumnName".equals(propName)) {
			columnName = "ORDER_COLUMN_NAME";
		}else if("filterColumnName".equals(propName)) {
			columnName = "FILTER_COLUMN_NAME";
		}else if("attachmentTableName".equals(propName)) {
			columnName = "ATTACHMENT_TABLE_NAME";
		}else if("attachmentBusinessIdColumn".equals(propName)) {
			columnName = "ATTACHMENT_BUSINESS_ID_COLUMN";
		}else if("attachmentIdColumn".equals(propName)) {
			columnName = "ATTACHMENT_ID_COLUMN";
		}else if("attachmentNameColumn".equals(propName)) {
			columnName = "ATTACHMENT_NAME_COLUMN";
		}else if("attachmentOrderColumn".equals(propName)) {
			columnName = "ATTACHMENT_ORDER_COLUMN";
		}else if("ordnum".equals(propName)) {
			columnName = "ORDNUM";
			value = Convert.toInt(value, 0);
		}else throw new HException("不能识别的属性名：" + propName);
		dataTableDao.updateValue(id, columnName, value);		
	}
	
	/** 根据ID删除 DAYU-表视图定义,按顺序号进行left join 
	 * @param id	主键值
	 * @return void
	 * @throws Exception
	 * @author wanghua
	 */
	public void deleteDataTable(Long id) throws Exception{		
		dataTableDao.deleteDataTable(id);
		dataColumnService.deleteDataColumns(id);
	}

	/** property **/
	@Autowired
	private DataTableDao dataTableDao;
	
	@Autowired
	private ProjectService projectService;
	
	@Autowired
	private DataColumnService dataColumnService;
	@Autowired
	private FuncService funcService;
}
